package edu.cicese.alz;

import edu.cicese.alz.swing.dialogs.CustomDialog;
import edu.cicese.alz.swing.SwingUtil;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.LineBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;

/**
 * Created by: Eduardo Quintana Contreras
 * Date: 21/06/12
 * Time: 02:52 AM
 */
public class DialogColorChooser extends CustomDialog {

	SwatchPanel swatchPanel;
	RecentSwatchPanel recentSwatchPanel;
	MouseListener mainSwatchListener;
	MouseListener recentSwatchListener;

	private Color selectedColor, oldColor;
	private JLabel lblColor;

	public static void main(String[] a) {
		SwingUtil.setUIManager();
		new DialogColorChooser(new JFrame(), Color.RED);
	}

	public DialogColorChooser(JFrame owner, Color oldColor) {
		super(owner, "Select color");

		setMin(450, 190);
		setInitialLocation();
		setResizable(false);

		setOldColor(oldColor);

		initComponents();
		setVisible(true);
	}

	public void initComponents() {
		JPanel pContent = new JPanel(new BorderLayout());

		JLabel lblSelectedColor = new JLabel("Selected color:");
		lblColor = SwingUtil.createLabel("", 80, 40);
		lblColor.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK),
				BorderFactory.createLineBorder(Color.WHITE)));
		lblColor.setOpaque(true);
		setSelectedColor(oldColor);

		JButton btnConfirm = SwingUtil.createButtonBackground("Confirm", 71, 22, null,
				getIcon("bg"), getIcon("bgO"), getIcon("bgP"));
		btnConfirm.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				actionConfirm();
			}
		});

		JButton btnCancel = SwingUtil.createButtonBackground("Cancel", 71, 22, null,
				getIcon("bg"), getIcon("bgO"), getIcon("bgP"));
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				actionCancel();
			}
		});

		Box boxTop = Box.createHorizontalBox();
		boxTop.add(btnConfirm);
		boxTop.add(Box.createHorizontalStrut(7));
		boxTop.add(btnCancel);
		boxTop.add(Box.createHorizontalStrut(15));
		boxTop.add(lblSelectedColor);
		boxTop.add(Box.createHorizontalStrut(5));
		boxTop.add(lblColor);


		swatchPanel = new MainSwatchPanel();
		recentSwatchPanel = new RecentSwatchPanel();

		mainSwatchListener = new MainSwatchListener();
		swatchPanel.addMouseListener(mainSwatchListener);
		recentSwatchListener = new RecentSwatchListener();
		recentSwatchPanel.addMouseListener(recentSwatchListener);

		JPanel mainHolder = new JPanel(new BorderLayout());
		Border border = new CompoundBorder(new LineBorder(Color.BLACK),
				new LineBorder(Color.WHITE));
		mainHolder.setBorder(border);
		mainHolder.add(swatchPanel, BorderLayout.CENTER);

		JLabel lblRecent = new JLabel("Recent:");
		lblRecent.setLabelFor(recentSwatchPanel);

		JPanel recentHolder = new JPanel(new BorderLayout());
		recentHolder.setBorder(border);
		recentHolder.add(recentSwatchPanel, BorderLayout.CENTER);

		Box boxSwatches = Box.createHorizontalBox();
		boxSwatches.add(Box.createHorizontalStrut(10));
		boxSwatches.add(mainHolder);
		boxSwatches.add(Box.createHorizontalStrut(10));
		boxSwatches.add(recentHolder);
		boxSwatches.add(Box.createHorizontalStrut(10));



		JPanel pSwatches = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();

		gbc.anchor = GridBagConstraints.LAST_LINE_START;
		gbc.gridwidth = 1;
		gbc.gridheight = 2;
		gbc.insets = new Insets(0, 0, 0, 10);
		pSwatches.add(mainHolder, gbc);

		gbc.insets = new Insets(0, 0, 0, 0);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbc.gridheight = 1;
		gbc.weighty = 1.0;
		pSwatches.add(lblRecent, gbc);

		gbc.weighty = 0;
		gbc.gridheight = GridBagConstraints.REMAINDER;
		pSwatches.add(recentHolder, gbc);


		Box boxMain = Box.createVerticalBox();
		boxMain.add(Box.createVerticalStrut(5));
		boxMain.add(boxTop);
		boxMain.add(Box.createVerticalStrut(5));
		boxMain.add(pSwatches);
		boxMain.add(Box.createVerticalStrut(5));

		pContent.add(boxMain);

		setContentPane(pContent);
	}

	public void setOldColor(Color oldColor) {
		this.oldColor = oldColor;
	}

	private void setSelectedColor(Color color) {
		lblColor.setBackground(color);
	}

	private void actionConfirm() {
		this.selectedColor = lblColor.getBackground();
	}

	private void actionCancel() {
		setVisible(false);
	}



	class RecentSwatchListener extends MouseAdapter implements Serializable {
		public void mousePressed(MouseEvent e) {
			if (isEnabled()) {
				Color color = recentSwatchPanel.getColorForLocation(e.getX(), e.getY());
				setSelectedColor(color);
			}
		}
	}

	class MainSwatchListener extends MouseAdapter implements Serializable {
		public void mousePressed(MouseEvent e) {
			if (isEnabled()) {
				Color color = swatchPanel.getColorForLocation(e.getX(), e.getY());
				setSelectedColor(color);
				recentSwatchPanel.setMostRecentColor(color);
			}
		}
	}


	class SwatchPanel extends JPanel {

		protected Color[] colors;
		protected Dimension swatchSize;
		protected Dimension numSwatches;
		protected Dimension gap;

		public SwatchPanel() {
			initValues();
			initColors();
			setToolTipText(""); // register for events
			setOpaque(true);
			setBackground(Color.white);
			setRequestFocusEnabled(false);
			setInheritsPopupMenu(true);
		}

		public boolean isFocusTraversable() {
			return false;
		}

		protected void initValues() {

		}

		public void paintComponent(Graphics g) {
			g.setColor(getBackground());
			g.fillRect(0, 0, getWidth(), getHeight());
			for (int row = 0; row < numSwatches.height; row++) {
				int y = row * (swatchSize.height + gap.height);
				for (int column = 0; column < numSwatches.width; column++) {

					g.setColor(getColorForCell(column, row));
					int x;
					if ((!this.getComponentOrientation().isLeftToRight()) &&
							(this instanceof RecentSwatchPanel)) {
						x = (numSwatches.width - column - 1) * (swatchSize.width + gap.width);
					} else {
						x = column * (swatchSize.width + gap.width);
					}
					g.fillRect(x, y, swatchSize.width, swatchSize.height);
					g.setColor(Color.black);
					g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1, y + swatchSize.height - 1);
					g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y + swatchSize.height - 1);
				}
			}
		}

		public Dimension getPreferredSize() {
			int x = numSwatches.width * (swatchSize.width + gap.width) - 1;
			int y = numSwatches.height * (swatchSize.height + gap.height) - 1;
			return new Dimension(x, y);
		}

		protected void initColors() {


		}

		public String getToolTipText(MouseEvent e) {
			Color color = getColorForLocation(e.getX(), e.getY());
			return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
		}

		public Color getColorForLocation(int x, int y) {
			int column;
			if ((!this.getComponentOrientation().isLeftToRight()) &&
					(this instanceof RecentSwatchPanel)) {
				column = numSwatches.width - x / (swatchSize.width + gap.width) - 1;
			} else {
				column = x / (swatchSize.width + gap.width);
			}
			int row = y / (swatchSize.height + gap.height);
			return getColorForCell(column, row);
		}

		private Color getColorForCell(int column, int row) {
			return colors[(row * numSwatches.width) + column]; // (STEVE) - change data orientation here
		}


	}

	class RecentSwatchPanel extends SwatchPanel {
		protected void initValues() {
			swatchSize = UIManager.getDimension("ColorChooser.swatchesRecentSwatchSize", getLocale());
			numSwatches = new Dimension(5, 7);
			gap = new Dimension(1, 1);
		}


		protected void initColors() {
			Color defaultRecentColor = UIManager.getColor("ColorChooser.swatchesDefaultRecentColor", getLocale());
			int numColors = numSwatches.width * numSwatches.height;

			colors = new Color[numColors];
			for (int i = 0; i < numColors; i++) {
				colors[i] = defaultRecentColor;
			}
		}

		public void setMostRecentColor(Color c) {
			System.arraycopy(colors, 0, colors, 1, colors.length - 1);
			colors[0] = c;
			repaint();
		}

	}

	class MainSwatchPanel extends SwatchPanel {

		protected void initValues() {
			swatchSize = UIManager.getDimension("ColorChooser.swatchesSwatchSize", getLocale());
			numSwatches = new Dimension(31, 9);
			gap = new Dimension(1, 1);
		}

		protected void initColors() {
			int[] rawValues = initRawValues();
			int numColors = rawValues.length / 3;

			colors = new Color[numColors];
			for (int i = 0; i < numColors; i++) {
				colors[i] = new Color(rawValues[(i * 3)], rawValues[(i * 3) + 1], rawValues[(i * 3) + 2]);
			}
		}

		private int[] initRawValues() {
			int[] rawValues = {
					255, 255, 255, // first row.
					204, 255, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					255, 204, 255,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 204, 204,  // second row.
					153, 255, 255,
					153, 204, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					204, 153, 255,
					255, 153, 255,
					255, 153, 204,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 204, 153,
					255, 255, 153,
					204, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 204,
					204, 204, 204,  // third row
					102, 255, 255,
					102, 204, 255,
					102, 153, 255,
					102, 102, 255,
					102, 102, 255,
					102, 102, 255,
					102, 102, 255,
					102, 102, 255,
					153, 102, 255,
					204, 102, 255,
					255, 102, 255,
					255, 102, 204,
					255, 102, 153,
					255, 102, 102,
					255, 102, 102,
					255, 102, 102,
					255, 102, 102,
					255, 102, 102,
					255, 153, 102,
					255, 204, 102,
					255, 255, 102,
					204, 255, 102,
					153, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 153,
					102, 255, 204,
					153, 153, 153, // fourth row
					51, 255, 255,
					51, 204, 255,
					51, 153, 255,
					51, 102, 255,
					51, 51, 255,
					51, 51, 255,
					51, 51, 255,
					102, 51, 255,
					153, 51, 255,
					204, 51, 255,
					255, 51, 255,
					255, 51, 204,
					255, 51, 153,
					255, 51, 102,
					255, 51, 51,
					255, 51, 51,
					255, 51, 51,
					255, 102, 51,
					255, 153, 51,
					255, 204, 51,
					255, 255, 51,
					204, 255, 51,
					153, 255, 51,
					102, 255, 51,
					51, 255, 51,
					51, 255, 51,
					51, 255, 51,
					51, 255, 102,
					51, 255, 153,
					51, 255, 204,
					153, 153, 153, // Fifth row
					0, 255, 255,
					0, 204, 255,
					0, 153, 255,
					0, 102, 255,
					0, 51, 255,
					0, 0, 255,
					51, 0, 255,
					102, 0, 255,
					153, 0, 255,
					204, 0, 255,
					255, 0, 255,
					255, 0, 204,
					255, 0, 153,
					255, 0, 102,
					255, 0, 51,
					255, 0, 0,
					255, 51, 0,
					255, 102, 0,
					255, 153, 0,
					255, 204, 0,
					255, 255, 0,
					204, 255, 0,
					153, 255, 0,
					102, 255, 0,
					51, 255, 0,
					0, 255, 0,
					0, 255, 51,
					0, 255, 102,
					0, 255, 153,
					0, 255, 204,
					102, 102, 102, // sixth row
					0, 204, 204,
					0, 204, 204,
					0, 153, 204,
					0, 102, 204,
					0, 51, 204,
					0, 0, 204,
					51, 0, 204,
					102, 0, 204,
					153, 0, 204,
					204, 0, 204,
					204, 0, 204,
					204, 0, 204,
					204, 0, 153,
					204, 0, 102,
					204, 0, 51,
					204, 0, 0,
					204, 51, 0,
					204, 102, 0,
					204, 153, 0,
					204, 204, 0,
					204, 204, 0,
					204, 204, 0,
					153, 204, 0,
					102, 204, 0,
					51, 204, 0,
					0, 204, 0,
					0, 204, 51,
					0, 204, 102,
					0, 204, 153,
					0, 204, 204,
					102, 102, 102, // seventh row
					0, 153, 153,
					0, 153, 153,
					0, 153, 153,
					0, 102, 153,
					0, 51, 153,
					0, 0, 153,
					51, 0, 153,
					102, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 102,
					153, 0, 51,
					153, 0, 0,
					153, 51, 0,
					153, 102, 0,
					153, 153, 0,
					153, 153, 0,
					153, 153, 0,
					153, 153, 0,
					153, 153, 0,
					102, 153, 0,
					51, 153, 0,
					0, 153, 0,
					0, 153, 51,
					0, 153, 102,
					0, 153, 153,
					0, 153, 153,
					51, 51, 51, // eigth row
					0, 102, 102,
					0, 102, 102,
					0, 102, 102,
					0, 102, 102,
					0, 51, 102,
					0, 0, 102,
					51, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 51,
					102, 0, 0,
					102, 51, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					51, 102, 0,
					0, 102, 0,
					0, 102, 51,
					0, 102, 102,
					0, 102, 102,
					0, 102, 102,
					0, 0, 0, // ninth row
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					0, 51, 0,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					51, 51, 51};
			return rawValues;
		}
	}
}
